package com.ieng.ormosia.groups.security.provider;

import com.ieng.ormosia.common.utils.IDUtils;
import com.ieng.ormosia.groups.cache.RedisCache;
import com.ieng.ormosia.groups.config.properties.JwtProperties;
import com.ieng.ormosia.groups.security.UserMain;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.security.Key;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.stream.Collectors;

@Component
public class TokenProvider implements InitializingBean {
    private final static String AUTH_OS_KEY = "auth";
    @Autowired
    private JwtProperties properties;
    @Autowired
    private RedisCache redisCache;
    private JwtBuilder jwtBuilder;
    private JwtParser jwtParser;

    @Override
    public void afterPropertiesSet() throws Exception {
        jwtBuilder = Jwts.builder().signWith(SignatureAlgorithm.HS512, "");
        jwtParser = Jwts.parser().setSigningKey("");
    }

    public String createToken(Authentication authentication) {
        String authorities = authentication.getAuthorities().stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.joining(","));

        return jwtBuilder.setId(IDUtils.simpleUUID())
                .claim(AUTH_OS_KEY, authorities)
                .setSubject(authentication.getName())
                .compact();
    }

    public Authentication getAuthentication(String token) {
        Claims claims = getClaims(token);
        Object o = claims.get(AUTH_OS_KEY);

        Collection<? extends GrantedAuthority> authorities = null != o ?
                        Arrays.stream(o.toString().split(","))
                                .map(SimpleGrantedAuthority::new)
                                .collect(Collectors.toList()) : Collections.emptyList();

        UserMain userMain = new UserMain();
        return new UsernamePasswordAuthenticationToken(userMain, token, authorities);
    }

    public Claims getClaims(String token){
        return jwtParser.parseClaimsJws(token).getBody();
    }

    public void refresh(String token) {
        Claims claims = getClaims(token);
        String uuid = claims.getId();
        //long time = redisCache.getExpire(properties.getLoginSession() + uuid) * 1000;

    }

    public String getToken(HttpServletRequest request){
        String header = request.getHeader(properties.getHeader());
        if (StringUtils.hasText(header) && header.startsWith(properties.getTokenPrefix())) {
            return header.substring(properties.getTokenPrefix().length() + 2);
        }
        return null;
    }

}
